/*
 *  Copyright (c) 2022 ZhuHai Jieli Technology Co.,Ltd.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "typedef.h"
#include "utils_file.h"

static char sbuf[4096];

#define WIFI_FILE "/jieli/wifi.cfg"
#define WIFI_FILE_EXIST 1
#define WIFI_FILE_UNEXIST 0

static BOOL IsFileExist(const char *path)
{
    if (path == NULL) {
        return false;
    }
    int32_t fd = UtilsFileOpen(path, O_RDONLY_FS, 0);
    if (fd < 0) {
        return false;
    }
    (void)UtilsFileClose(fd);
    return true;
}

int syscfg_read(u16 item_id, void *buf, u16 len)
{
    int fd;
    unsigned int fileLen = 0;
    int ret;
    BOOL isFileExist = false;

    if (buf == NULL) {
        return -1;
    }

    if (IsFileExist(WIFI_FILE) == true) {
        isFileExist = true;
    }
    char syscfg_filename[64];
    sprintf_s(syscfg_filename, sizeof(syscfg_filename), "/jieli/wifi%d.cfg", item_id);
    printf("syscfg_filename=>%s\n", syscfg_filename);
    fd = UtilsFileOpen(syscfg_filename, O_RDWR_FS | O_CREAT_FS, 0);
    if (fd < 0) {
        return -1;
    }
    ret = UtilsFileStat(WIFI_FILE, &fileLen);
    if (ret != 0) {
        UtilsFileClose(fd);
        return -1;
    }

    ret = UtilsFileSeek(fd, 0, SEEK_SET_FS);
    if (ret != 0) {
        UtilsFileClose(fd);
        return -1;
    }
    if (fileLen > len) {
        UtilsFileClose(fd);
        return -1;
    }
    if (isFileExist == true) {
        ret = UtilsFileRead(fd, (char *)buf, len);
        if (ret <= 0) {
            UtilsFileClose(fd);
            return -1;
        }
    } else {
        ret = -1;
    }
    printf("syscfg read item_id:%d   len:%d\n", item_id, ret);
    UtilsFileClose(fd);
    return ret;
}

int syscfg_write(u16 item_id, void *buf, u16 len)
{
    printf("syscfg write item_id:%d   len:%d\n", item_id, len);

    int fd;

    if (buf == NULL) {
        return -1;
    }

    char syscfg_filename[64];
    sprintf_s(syscfg_filename, sizeof(syscfg_filename), "/jieli/wifi%d.cfg", item_id);

    printf("syscfg_filename=>%s\n", syscfg_filename);
    fd = UtilsFileOpen(syscfg_filename, O_RDWR_FS | O_CREAT_FS | O_TRUNC_FS, 0);
    if (fd < 0) {
        return -1;
    }
    if (UtilsFileWrite(fd, (const char *)buf, len) < 0) {
        UtilsFileClose(fd);
        return -1;
    }
    UtilsFileClose(fd);

    return len;
}

unsigned int random32(int type)
{
    return CPU_RAND();
}

void get_random_bytes(unsigned char *buf, int nbytes)
{
    while (nbytes--) {
        *buf = random32(0);
        ++buf;
    }
}

int rand_val(void *p_rng, unsigned char *output, unsigned int output_len)
{
    get_random_bytes(output, output_len);
    return 0;
}

const int config_asser         = 1;
void cpu_assert_debug()
{
    printf("%s  %d\n", __func__, __LINE__);
    cpu_reset();
}

void put_u4hex(unsigned char dat)
{
    dat = 0xf & dat;

    if (dat > 9) {
        putchar(dat - 10 + 'A');
    } else {
        putchar(dat + '0');
    }
}

_WEAK_
void put_u8hex(u8 dat)
{
    put_u4hex(dat >> 4);
    put_u4hex(dat);
    putchar(' ');
}

void put_buf(const u8 *buf, int len)
{

    for (int i = 0; i < len; i++) {
        if ((i % 16) == 0) {
            putchar('\n') ;
        }
        put_u8hex(buf[i]) ;
    }
    putchar('\n') ;
}

void printf_buf(u8 *buf, u32 len)
{
    put_buf(buf, len);
}

int bytecmp(unsigned char *p, unsigned char ch, unsigned int num)
{
    while (num-- > 0) {
        if (*p++ != ch) {
            return -1;
        }
    }
    return 0;
}

void  __assert_func()
{
}

void putbyte(char a)
{
}

const int SDFILE_VFS_REDUCE_ENABLE = 0;

void *dev_open(const char *name, void *arg)
{
    printf("%s   %d\n", __func__, __LINE__);
    return NULL;
}

int dev_read(void *device, void *buf, u32 len)
{
    printf("%s   %d\n", __func__, __LINE__);
    return 0;
}

int dev_write(void *device, void *buf, u32 len)
{
    printf("%s   %d\n", __func__, __LINE__);
    return 0;
}

int dev_ioctl(void *device, int cmd, u32 arg)
{
    printf("%s   %d\n", __func__, __LINE__);
    return 0;
}

int dev_close(void *device)
{
    printf("%s   %d\n", __func__, __LINE__);
    return 0;
}

// 实现功能函数 无效函数 需要实现
void low_power_hw_unsleep_lock(void)
{
    printf("%s   %d\n", __func__, __LINE__);
}

// 实现功能函数 无效函数 需要实现
void low_power_hw_unsleep_unlock(void)
{
    printf("%s   %d\n", __func__, __LINE__);
}

// BR28 未实现函数
void hw_periph_exit_deepsleep(void)
{
    printf("%s   %d\n", __func__, __LINE__);
}

#define SFC1_FLASH_BASE_ADDR                  0 // 外置flash使用sfc1访问开始物理地址
#define SFC1_AXI_BUS_BASE_ADDR                0x4000000 // AXI BUS访问sfc1基址
#define SFC1_AXI_BUS_CPU_BASE_ADDR            0x4000000 // CPU访问sfc1基址
#define AT_VLOLATILE_RAM        sec(.volatile_ram_code)

AT_VLOLATILE_RAM
u32 sfc1_flash_addr2cpu_addr(u32 offset)
{
    return offset + SFC1_AXI_BUS_CPU_BASE_ADDR;
}

AT_VLOLATILE_RAM
u32 sfc1_cpu_addr2flash_addr(u32 offset)
{
    return offset - SFC1_AXI_BUS_CPU_BASE_ADDR;
}

// driver_config.c

// 不适用FM
u8 br23_fm_tx_mode(void)
{
    return 0;
}

u8 fm_tx_ch(void)
{
    return 0;
}
u8 is_lcd_on(void)
{
    return 0;
}

